/**
 * <p>Tilte:ValidateHelper.java</p>
 * <p>Version:v1.0 </p>
 * <p>Copyright ©2011 ... Technology Co.,Ltd.All Rights Reserved</p>
 */
package com.company.common.core.checker;

import org.apache.commons.lang3.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author: simon (fq_zxy.com)
 * @notes : 验证帮助类
 * @date :2011-9-23
 */
public final class ValidateHelper {
	/**
	 * 身份证号码校验,成功返回生日格式：20000101 失败返回""
	 * 
	 * @param idCardStr
	 *            身份证号码
	 * @return 提取的生日,格式为20000101
	 */
	public static boolean isIDC(String idCardStr) {
		if (idCardStr.length() == 15) {
			try {
				idCardStr = IdCardTransfer(idCardStr);
			} catch (Exception e) {
				return false;
			}
		}
		if (idCardStr.length() != 18) {
			return false;
		}
		// 验证出生日期
		if (!isBirthday(idCardStr.substring(6, 10) + "-" + idCardStr.substring(10, 12) + "-" + idCardStr.substring(12, 14))) {
			return false;
		}
		// 验证校验码
		int sigma = 0;
		Integer[] a = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
		String[] w = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
		for (int i = 0; i < 17; i++) {
			int ai = Integer.parseInt(idCardStr.substring(i, i + 1));
			int wi = a[i];
			sigma += ai * wi;
		}
		int number = sigma % 11;
		String check_number = w[number];
		if (!idCardStr.substring(17).equals(check_number)) {
			return false;
		} else {
			return true;
		}

	}

	/**
	 * 验证生日是否合法,日期格式为2011-10-31
	 * 
	 * @param birth
	 * @return
	 */
	public static boolean isBirthday(String birth) {
		boolean flag = false;
		StringBuffer sb = new StringBuffer();
		sb.append("^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))").append("|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))")
				.append("|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-").append("(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])").append("|((16|[2468][048]|[3579][26])00))-0?2-29))$");
		Pattern pt = Pattern.compile(sb.toString());
		if (pt.matcher(birth).matches()) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 验证邮政编码
	 */
	public static boolean isPostCode(String postCode) {
		String reg = "^[0-9]{6}$";
		Pattern pt = Pattern.compile(reg);
		return pt.matcher(postCode).matches();

	}

	/**
	 * 身份证转换方法，15位的转为18位；相应的18位的转为15位
	 */
	public static String IdCardTransfer(String numToTransfer) throws Exception {
		String newId = "";
		String tmp17 = "";
		if (numToTransfer.length() == 18) {
			newId = numToTransfer.substring(0, 6) + numToTransfer.substring(8, 17);
		} else if (numToTransfer.length() == 15) {
			tmp17 = numToTransfer.substring(0, 6) + "19" + numToTransfer.substring(6);
			String code; // 第18位校验位
			int num = 0;
			for (int i = 18; i > 1; i--)
				num += (int) Math.pow(2, i - 1) % 11 * Integer.valueOf("" + tmp17.charAt(18 - i)).intValue();
			num %= 11;
			switch (num) {
			case 0:
				code = "1";
				break;
			case 1:
				code = "0";
				break;
			case 2:
				code = "X";
				break;
			default:
				code = 12 - num + "";
				break;
			}
			newId = tmp17 + code;
		} else if (numToTransfer.length() == 17) {
			tmp17 = numToTransfer;
			String code; // 第18位校验位
			int num = 0;
			for (int i = 18; i > 1; i--)
				num += (int) Math.pow(2, i - 1) % 11 * Integer.valueOf("" + tmp17.charAt(18 - i)).intValue();
			num %= 11;
			switch (num) {
			case 0:
				code = "1";
				break;
			case 1:
				code = "0";
				break;
			case 2:
				code = "X";
				break;
			default:
				code = 12 - num + "";
				break;
			}
			newId = tmp17 + code;
		} else {
			throw new Exception("身份证号码位数错误！！");
		}

		return newId;
	}

	/**
	 * 根据Excel文件中的列标（A,AA,C,CX）返回是第几列（从0开始）。
	 * 返回值是-1说明参数不是有效的列标(Excel文件至多可有256列，A--IV)
	 * 
	 * @param col
	 * @return
	 * @throws Exception
	 */
	public static int checkExcelCol(String col) throws Exception {
		int rtn = -1;
		if (col == null || "".equals(col))
			return -1;
		if (col.length() < 1 || col.length() > 2) {
			return -1;
		}
		col = col.toUpperCase();
		// Excel最多256列，从A---IV
		if (col.length() == 1) {
			char a1 = col.charAt(0);
			int i1 = (int) a1;
			if (i1 < 65 || i1 > 90) // 不是A---Z
				return -1;
			rtn = i1 - 64 - 1;
		}
		if (col.length() == 2) {
			char a1 = col.charAt(0);
			int i1 = (int) a1;
			if (i1 < 65 || i1 > 73) // 不是A---I
				return -1;
			else {
				char a2 = col.charAt(1);
				int i2 = (int) a2;
				if (i2 < 65 || i2 > 90) // 不是A---Z
					return -1;
				if (i1 == 73 && i2 > 86)// 第一个为I,第二个至多为 V
					return -1;
				rtn = (i1 - 64) * 26 + (i2 - 64) - 1;
			}
		}
		return rtn;
	}

	// 检查身份证是否有不合法字符
	public static boolean checkValid(String idCard) {
		for (int i = 0; i < idCard.length(); i++) {
			char m = idCard.charAt(i);
			if (i < 17 && (m < '0' || m > '9')) {
				return false;
			}
			if (i == 17) {
				if (m >= '0' && m <= '9')
					return true;
				else if (m == 'x' || m == 'X')
					return true;
				else
					return false;
			}
		}
		return true;
	}

	// 判断合法日期
	public static String[] checkDate(String year, String month, String day) {
		int yearValue = Integer.parseInt(year);
		int monthValue = Integer.parseInt(month);
		int dayValue = Integer.parseInt(day);

		if (yearValue >= 2100 || yearValue <= 1900) {
			return null;
		}
		if (monthValue < 1 || monthValue > 12) {
			return null;
		}
		if (dayValue < 1 || dayValue > 31) {
			return null;
		}
		if (((monthValue == 4 || monthValue == 6 || monthValue == 9 || monthValue == 11) && dayValue > 30) || (monthValue == 2 && dayValue > 29)
				|| ((monthValue == 2 && dayValue > 28 && !((yearValue % 4 == 0 && yearValue % 100 != 0) || (yearValue % 400 == 0))))) {
			return null;
		}

		return new String[] { year, month, day };
	}

	public static String validIdCardNum(String idCard) throws Exception {
		String errMsg = null;
		if (idCard.length() == 15 || idCard.length() == 18) {
			if (!checkValid(idCard)) {
				errMsg = "错误：身份证号码有错误字符！";
				return errMsg;
			}
			if (idCard.length() == 18) {
				String id18 = ValidateHelper.IdCardTransfer(idCard.substring(0, 17));
				if (!(id18.equals(idCard))) {
					errMsg += "身份证号码不对！   ";
					return errMsg;
				}
				String[] birthday = checkDate(idCard.substring(6, 10), idCard.substring(10, 12), idCard.substring(12, 14));
				if (birthday == null) {
					errMsg += "生日可能不正确！   ";
					return errMsg;
				}
			}
			if (idCard.length() == 15) {
				String[] birthday = checkDate("19" + idCard.substring(6, 8), idCard.substring(8, 10), idCard.substring(10, 12));
				if (birthday == null) {
					errMsg += "生日可能不正确！   ";
					return errMsg;
				}
			}
			if ("".equals(errMsg))
				errMsg = "正确：本身份证号码通过校验！";
		} else {
			errMsg = "身份证位数错误！";
			return errMsg;
		}
		return errMsg;
	}

	/**
	 * 根据正则表达式校验,正则表达式自己填
	 * 
	 * @param value
	 * @param regExp
	 * @return
	 */
	public static boolean validFieldByRegExp(String value, String regExp) {
		if (StringUtils.isEmpty(value))
			return false;
		Pattern pattern = Pattern.compile(regExp);
		Matcher matcher = pattern.matcher(value);

		if (matcher.matches()) {
			return true;
		} else {
			return false;
		}
	}

	// 根据身份证获取生日
	public static String getBirthdayByIDC(String idNum) {
		StringBuffer birthday = new StringBuffer();
		String year = idNum.substring(6, 10);
		String month = idNum.substring(10, 12);
		String day = idNum.substring(12, 14);
		birthday.append(year).append("-").append(month).append("-").append(day);
		return birthday.toString();
	}

}
